#include "bga/system/File.h"
#include "bga/system/BoardHellException.h"

using namespace std;

namespace bga
{

File::File(const string& filename) : fullName(filename)
{
}

File::File(const File& copy) : fullName(copy.fullName)
{

}

File::~File()
{

}

File& File::operator=(const File& file)
{
    this->fullName = file.fullName;
    return *this;
}

bool File::exists() const
{
    ifstream stream(this->fullName.c_str());
    return stream.is_open();
}

bool File::exists(const std::string& filename, const std::string& directory)
{
    ///Test of existence on dirent structure. Take care maybe not portable
    /// Drawback of the method : have to parse directory to find the file/directory

    /// TODO : handle with two and more level of directories
    DIR *dir;
    dir = opendir(directory.c_str());
    return File::readDir(dir, filename);

}

bool File::readDir(DIR* dir, const std::string& filename)
{
    bool res = false;
    dirent *reading;
    seekdir(dir, 2);
    while ((reading = readdir(dir)))
    {
        string fileReaded(reading->d_name);

        if(filename == fileReaded)
        {
            res = true;
            break;
        }

        DIR* currentDir;
        if((currentDir = opendir(reading->d_name)) != NULL)
        {
            res = readDir(currentDir, filename);
        }
    }
    closedir(dir);
    return res;

}

void File::open()
{
    if(this->fullName.empty())
    {
        throw BoardHellException("No specified file to open");
    }

    if(!this->stream.is_open())
    {
        this->stream.open(this->fullName.c_str());
    }
}

void File::close()
{
    if(this->stream.is_open())
    {
        this->stream.close();
    }
}

const std::string& File::getFullName() const
{
    return this->fullName;
}

}
